package com.promise.jokerdream.task.base

import kotlinx.coroutines.*

/**
 * 串行任务基类
 * 支持按顺序执行一系列网络请求步骤
 */
abstract class SerialTask(
    name: String,
    taskType: TaskType,
    repeatCount: Int = 1
) : BaseTask(name, taskType, repeatCount) {
    
    /**
     * 获取任务步骤列表
     * 子类需要实现此方法来提供具体的步骤
     */
    abstract fun getSteps(): List<NetworkStep>
    
    /**
     * 执行串行网络请求步骤
     */
    override suspend fun doExecute(): TaskResult {
        val steps = getSteps()
        if (steps.isEmpty()) {
            return TaskResult.Success
        }
        
        val context = RequestContext()
        
        return try {
            // 按顺序执行所有步骤
            for ((index, step) in steps.withIndex()) {
                context.currentStepIndex = index
                
                val stepResult = executeStep(step, context)
                context.setStepResult(step.stepName, stepResult)
                
                // 检查步骤结果
                when (stepResult) {
                    is StepResult.Success -> {
                        // 步骤成功，继续下一个
                        continue
                    }
                    is StepResult.Failure -> {
                        // 步骤失败，终止整个任务
                        return TaskResult.Failure(
                            Exception("Step '${step.stepName}' failed: ${stepResult.message}")
                        )
                    }
                    is StepResult.Skipped -> {
                        // 步骤被跳过，继续下一个
                        continue
                    }
                }
            }
            
            // 所有步骤执行完成
            TaskResult.Success
        } catch (e: CancellationException) {
            TaskResult.Cancelled
        } catch (e: Exception) {
            TaskResult.Failure(e)
        }
    }
    
    /**
     * 执行单个步骤
     */
    private suspend fun executeStep(step: NetworkStep, context: RequestContext): StepResult {
        return try {
            step.execute(context)
        } catch (e: Exception) {
            StepResult.Failure(e, "Step '${step.stepName}' execution failed")
        }
    }
    
    /**
     * 获取任务统计信息
     */
    fun getTaskStats(): TaskStats {
        val steps = getSteps()
        if (steps.isEmpty()) {
            return TaskStats(
                totalSteps = 0,
                successSteps = 0,
                failureSteps = 0,
                successRate = 0f
            )
        }
        
        // 这里需要从执行过程中收集统计信息
        // 暂时返回默认值，实际实现中需要保存执行结果
        return TaskStats(
            totalSteps = steps.size,
            successSteps = 0,
            failureSteps = 0,
            successRate = 0f
        )
    }
}

/**
 * 网络请求步骤接口
 */
interface NetworkStep {
    /**
     * 步骤名称
     */
    val stepName: String
    
    /**
     * 执行网络请求步骤
     * @param context 请求上下文，包含之前步骤的结果数据
     * @return 步骤执行结果
     */
    suspend fun execute(context: RequestContext): StepResult
}

/**
 * 请求上下文
 * 用于在步骤之间传递数据
 */
data class RequestContext(
    /**
     * 步骤结果映射，key为步骤名称，value为步骤结果
     */
    val stepResults: MutableMap<String, StepResult> = mutableMapOf(),
    
    /**
     * 共享数据，用于步骤间传递自定义数据
     */
    val sharedData: MutableMap<String, Any> = mutableMapOf(),
    
    /**
     * 当前步骤索引
     */
    var currentStepIndex: Int = 0
) {
    /**
     * 获取指定步骤的结果
     */
    fun getStepResult(stepName: String): StepResult? = stepResults[stepName]
    
    /**
     * 设置步骤结果
     */
    fun setStepResult(stepName: String, result: StepResult) {
        stepResults[stepName] = result
    }
    
    /**
     * 获取共享数据
     */
    @Suppress("UNCHECKED_CAST")
    fun <T> getSharedData(key: String): T? = sharedData[key] as? T
    
    /**
     * 设置共享数据
     */
    fun <T> setSharedData(key: String, value: T) {
        sharedData[key] = value as Any
    }
}

/**
 * 步骤执行结果
 */
sealed class StepResult {
    /**
     * 成功结果
     */
    data class Success(
        val data: String? = null,
        val headers: Map<String, String>? = null,
        val statusCode: Int? = null
    ) : StepResult()
    
    /**
     * 失败结果
     */
    data class Failure(
        val error: Throwable,
        val message: String? = null
    ) : StepResult()
    
    /**
     * 跳过结果（非必需步骤失败时）
     */
    object Skipped : StepResult()
}

/**
 * 任务统计信息
 */
data class TaskStats(
    val totalSteps: Int,
    val successSteps: Int,
    val failureSteps: Int,
    val successRate: Float
)